<?php

namespace app\api\controller;

use api\Xiaoju;
use app\api\service\OilXiaojuService;
use app\BaseController;
use app\model\AgentServiceConfig;
use app\model\BaseSupplier;
use app\model\DmjPlatformUsers;
use app\model\OilAgentChannel;
use app\model\OilOrder;
use app\model\OilOrderReceiveLog;
use app\Request;
use think\facade\Db;

/**
 * 小桔回调通知.
 */
class XiaojuNotify extends BaseController
{
    public $xiaoju;
    public $dataInit = '';
    public $data = [];
    public $reData = ['code' => 0, 'msg' => '请求成功'];

    public function __construct(Request $request, Xiaoju $xiaoju)
    {
        // 记录日志
        if ($request->param()) {
            doLog('接受小桔通知消息，参数：'.json_encode($request->param(), JSON_UNESCAPED_UNICODE));
            $this->xiaoju = $xiaoju;
            try {
                $this->data = $this->xiaoju->decrypt($request->param());
                doLog('接受小桔通知消息，解密后data：'.json_encode($this->data, JSON_UNESCAPED_UNICODE));
            } catch (\Exception $e) {
                doLog('接受小桔通知消息，解密错误：'.getExceptionMsg($e));
            }
        } else {
            doLog('接受小桔通知消息，参数为空');
            $this->xiaoju = $xiaoju;
        }
    }

    /**
     * 接受小桔平台用户校验接口.
     */
    public function notifyCheckUserInfo()
    {
        $resultData = ['checkState' => 1, 'checkMsg' => ''];
        $rules = [
            'mobile' => 'require',
            'outUserId' => 'require',
        ];

        $messages = ['mobile.require' => '手机号参数异常', 'outUserId.require' => '用户id异常'];
        if ($resultData['checkMsg'] = dmjValidate($rules, $messages, $this->data)) {
            return json($this->makeReturnData($resultData));
        }

        // 校验用户信息  对接均用platform_users表的id 否则由于订单都在小桔方，无法定位到代理商信息
        $userInfo = DmjPlatformUsers::withTrashed()->where([['mobile', '=', $this->data['mobile']], ['platform', '=', AGENT_USER_PLATFORM]])->find($this->data['outUserId']);
        if (!$userInfo) {
            $resultData['checkMsg'] = '用户信息不存在';

            return json($this->makeReturnData($resultData));
        }

        $resultData['checkState'] = 0;

        return json($this->makeReturnData($resultData));
    }

    /**
     * 订单通知.
     * {
     *   "outUserId": "out123456789",//第三方平台UserId
     *   "orderId": "3467771714635066313",
     *   "storeId": "5105493875147414159",
     *   "storeName": "自动化测试门店4",
     *   "cityName": "杭州市",
     *   "gunNo": "2",//枪号
     *   "itemName": "92#",
     *   "quantity": 1.2,//商品升数
     *   "totalMoney": 800,//订单金额、单位是分
     *   "realMoney": 800,//实付 金额、单位是分
     *   "payStatus": 1,//0未支付 1已支付
     *   "payTime": "2019-11-28 07:03:50",
     *   "refundStatus": 0,//0未退款 1已退款
     *   "payType": 1, // 支付方式： 0-其他 1-支付宝，2-微信
     *   "refundTime": null //未退款、无退款时间
     * }.
     */
    public function notifyOrderInfo()
    {
        $resultData = ['state' => 0, 'message' => ''];

        // 参数校验
        if (!$this->data) {
            $resultData['message'] = 'data不能为空';

            return json($this->makeReturnData($resultData));
        }

        $rules = [
            'outUserId' => 'require',
            'orderId' => 'require',
            'storeId' => 'require',
            'storeName' => 'require',
            'cityName' => 'require',
            'gunNo' => 'require',
            'itemName' => 'require',
            'quantity' => 'require',
            'totalMoney' => 'require',
            'realMoney' => 'require',
            'payStatus' => 'require',
            'payTime' => 'require',
        ];

        $messages = ['require' => '参数异常'];
        if ($resultData['message'] = dmjValidate($rules, $messages, $this->data)) {
            return json($this->makeReturnData($resultData));
        }

        // 根据用户id 用户所在渠道 以及 渠道方用户id对应的 平台的用户id
        $userInfo = DmjPlatformUsers::withTrashed()->find($this->data['outUserId']);
        if (AGENT_USER_PLATFORM != $userInfo->platform) {
            doWarning('小桔订单回调通知异常，根据用户查询代理商时 platform不是'.AGENT_USER_PLATFORM.'，防止意外仍然接受订单回调，清排查处理');
        }
        //查询代理商id
        $agentInfo = OilAgentChannel::find($userInfo->app_id);
        if (!$agentInfo) {
            $resultData['message'] = '我们出错了，请联系我们';
            doWarning('小桔订单回调通知异常，渠道对应的代理商信息不存在');

            return json($this->makeReturnData($resultData));
        }
        // 代理商业务配置
        $agentServiceConfig = AgentServiceConfig::where('agent_id', $agentInfo['agent_id'])->where('serv_type', PRODUCT_OIL_SERV)->find();
        if (!$agentServiceConfig) {
            doWarning('代理商加油配置不存在');
        }
        // 获取供应商
        $supplierInfo = $this->getSupplier();
        if (!$supplierInfo) {
            $resultData['message'] = '我们出错了，请联系我们';

            return json($this->makeReturnData($resultData));
        }

        // step 把字段转化成 数据库表字段
        $orderData = invoke(OilXiaojuService::class)->getOrderData($this->data);
        //step  其他参数完善
        $orderData['user_id'] = $userInfo->user_id;
        $orderData['cnid'] = $userInfo->app_id;
        $orderData['agent_id'] = $agentInfo['agent_id'];
        $orderData['supplier_id'] = $supplierInfo->id;

        // 计算代理商结算价格相关
        $orderData['agent_settle_type'] = $agentInfo->settle_type;
        $orderData['agent_settle_value'] = $agentServiceConfig->value;
        $orderData['agent_profit'] = calcOilCommiss($agentServiceConfig->value, $orderData['pay_amount']); //滴滴加油平台无法设置价格 用的是支付价格计算

        // 计算供应商结算价格相关
        $orderData['supplier_settle_type'] = $supplierInfo->settle_type;
        $orderData['supplier_settle_value'] = $supplierInfo->settle_value;
        $orderData['supplier_gate_rate'] = $supplierInfo->gate_rate;

        $supplierGateAmount = supplierGateAmount($orderData['pay_amount'], $supplierInfo->gate_rate);
        $supplierProfit = calcOilCommiss($supplierInfo->settle_value, $orderData['pay_amount']); //滴滴加油平台无法设置价格 用的是支付价格计算
        $orderData['profit'] = calcProfit($supplierProfit, $orderData['agent_profit'], $supplierGateAmount);

        // todo 订单数据合理性校验
        // 开启事务 入库数据
        Db::startTrans();
        try {
            $oilOrderReceiveLog = new OilOrderReceiveLog();
            $res = $oilOrderReceiveLog->save($orderData);
            if (!$res) {
                Db::rollback();
                $resultData['message'] = '操作失败，请联系我们';
            } else {
                // 查找订单 进行更新或者insert
                $oilOrder = OilOrder::where('out_order_id', $orderData['out_order_id'])->find();
                if (!$oilOrder) {
                    $oilOrder = new OilOrder();
                }
                $res = $oilOrder->save($orderData);
                if (!$res) {
                    Db::rollback();
                    $resultData['message'] = '操作失败，请联系我们';
                }
                Db::commit();
            }
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            doLog('小桔订单回调入库异常，'.getExceptionMsg($e));
            $resultData['message'] = '操作失败，请联系我们';
        }

        if ($resultData['message']) {
            return json($this->makeReturnData($resultData));
        }

        // 成功返回
        $resultData['state'] = 1;

        return json($this->makeReturnData($resultData));
    }

    /**
     * 获取供应商信息.
     **/
    private function getSupplier()
    {
        $supplierInfo = BaseSupplier::where('code', OIL_SUPPLIER_ALIAS['xiaoju']['alias'])->find();

        if (!$supplierInfo) {
            doLog('供应商信息不存在异常');
            doWarning('供应商信息不存在异常');

            return null;
        }

        return $supplierInfo;
    }

    public function makeReturnData($resultData)
    {
        return array_merge($this->xiaoju->encrypt($resultData, $this->dataInit, 0), $this->reData);
    }
}
